package com.rigi.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rigi.common.R;
import com.rigi.dto.SetmealDto;
import com.rigi.entity.Category;
import com.rigi.entity.Dish;
import com.rigi.entity.Setmeal;
import com.rigi.entity.SetmealDish;
import com.rigi.service.CategoryService;
import com.rigi.service.SetmealDishService;
import com.rigi.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/setmeal")
public class SetmealController {
    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增套餐
     *使用了CacheEvict注解的方法，会清空指定缓存
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "setmealCache",allEntries = true)
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto) {
        setmealService.saveWithSetmealDish(setmealDto);
        return R.success("新增套餐成功");
    }

    /**
     * 套餐分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page<SetmealDto>> page(int page, int pageSize, String name) {
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        Page<SetmealDto> setmealDtoPage = new Page<>();
        QueryWrapper<Setmeal> wrapper = new QueryWrapper<>();
        if (name != null) {
            wrapper.like("name", name);
        }
        wrapper.orderByDesc("update_time");
        setmealService.page(setmealPage, wrapper);
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");

        List<Setmeal> records = setmealPage.getRecords();
        List<SetmealDto> dtoArrayList = new ArrayList<>();
        dtoArrayList = records.stream().map(item -> {
            SetmealDto setmealDto = new SetmealDto();
            Category category = categoryService.getById(item.getCategoryId());
            BeanUtils.copyProperties(item, setmealDto);
            setmealDto.setCategoryName(category.getName());
            return setmealDto;
        }).collect(Collectors.toList());
        setmealDtoPage.setRecords(dtoArrayList);
        return R.success(setmealDtoPage);
    }

    /**
     * 删除套餐及菜品
     *
     * @param ids
     * @return
     */
    @CacheEvict(value = "setmealCache",allEntries = true)
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids) {
        setmealService.removeWithSetmealDish(ids);
        return R.success("删除成功");
    }

    @GetMapping("/{id}")
    public R<SetmealDto> get(@PathVariable long id) {
        SetmealDto setmealDto = setmealService.getByIdWithSetmealDish(id);

        return R.success(setmealDto);
    }

    /**
     * 修改套餐及菜品信息
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "setmealCache",allEntries = true)
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto){
        setmealService.updateWithSetmealDish(setmealDto);
        return R.success("修改成功");
    }

    /**
     * 修改套餐销售状态
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable int status,@RequestParam Long[] ids){
        List<Setmeal> setmeals = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            Setmeal setmeal = new Setmeal();
            setmeal.setStatus(status);
            setmeal.setId(ids[i]);
            setmeals.add(setmeal);
        }

        setmealService.updateBatchById(setmeals);
        return R.success("修改状态成功");
    }

    /**
     * @Cacheble注解表示这个方法有了缓存的功能，方法的返回值会被缓存下来，下一次调用该方法前，会去检查是否缓存中已经有值，如果有就直接返回，不调用方法。如果没有，就调用方法，然后把结果缓存起来
     * @param setmeal
     * @return
     */
    @Cacheable(value = "setmealCache",key = "#setmeal.categoryId+'_'+#setmeal.status")
    @GetMapping("/list")
    public R<List<SetmealDto>> list(Setmeal setmeal){
        QueryWrapper<Setmeal> wrapper = new QueryWrapper<>();
        wrapper.eq("category_id",setmeal.getCategoryId());
        List<Setmeal> list = setmealService.list(wrapper);

        List<SetmealDto> setmealDtos = new ArrayList<>();
        setmealDtos=list.stream().map(item->{
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item,setmealDto);
            QueryWrapper<SetmealDish> setmealDishQueryWrapper = new QueryWrapper<>();
            setmealDishQueryWrapper.eq("setmeal_id",item.getId());
            List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishQueryWrapper);
            setmealDto.setSetmealDishes(setmealDishes);
            return setmealDto;
        }).collect(Collectors.toList());


        return R.success(setmealDtos);
    }
}
